#!/usr/bin/perl
use strict;
use warnings;

use File::Glob ':glob';
use FileHandle;
use Fcntl ':flock';    # import LOCK_* constants
use Net::SMTP;

my $self_fh;
my $debug = 1;

my @mailfiles = bsd_glob('/home/woeishya/domains/ocfaustralia.org/connect/public_html/cgi-bin/mailqueue/*');

my $cur_base_filename;
my $cur_filename;

if ( !lockself() ) {
    die "Already running: " . scalar(@mailfiles) . " left in queue";
}

foreach my $filename (@mailfiles) {
    if ( -f $filename && $filename !~ /proc\.\d+$/ && $filename !~ /timedout$/ ) {
        my $starttime = time;
        warn "($starttime): Processing $filename" if $debug;
        eval {
            local $SIG{ALRM} = sub { die "timeout sending email" };
            alarm 60;
            processMailQueueFile($filename);
            alarm 0;
        };
        if ($@) {
            if ( $@ !~ /timeout sending email/ ) {
                die $@;
            } else {
                warn "Sending of email timed out" if $debug;
                rename($cur_filename, $cur_base_filename . ".timedout");
            }
        }
        while ( ( time - $starttime ) < 4 ) {
            sleep 1;
        }
    } ## end if ( -f $filename && $filename !~ /proc\.\d+$/)
} ## end foreach my $filename (@mailfiles)

sub lockself {
    my $scriptfile = $0;
    $self_fh = new FileHandle $scriptfile, "r";
    my $rv = flock( $self_fh, LOCK_EX | LOCK_NB );
    return $rv;
} ## end sub lockself

sub processMailQueueFile {
    my $filename = shift;
    $cur_base_filename = $filename;
    my $new_filename = $filename . ".proc." . time;
    if ( rename( $filename, $new_filename ) ) {
        warn "$filename renamed to $new_filename" if $debug;
        $filename     = $new_filename;
        $cur_filename = $filename;
    }
    warn "Opening $filename" if $debug;
    my $fh = new FileHandle $filename, "r";
    if ( $fh && flock( $fh, LOCK_EX | LOCK_NB ) ) {
        warn "Exclusive lock on file obtained" if $debug;
        my @filedata;
        while ( my $line = $fh->getline ) {
            chomp($line);
            push @filedata, $line;
        }

        $fh->close();

        my $to = shift(@filedata);
        warn "Sending email to $to" if $debug;
        my $smtp = Net::SMTP->new( 'Host' => 'localhost', 'Debug' => 0 );
        $smtp->auth( 'broadcast+connect.ocfaustralia.org', 'password' );
        $smtp->mail($to);
        $smtp->to($to);
        $smtp->data();

        foreach my $msgline (@filedata) {
            $msgline = $msgline . "\n";
            $smtp->datasend($msgline);
        }
        $smtp->dataend;
        $smtp->quit;
        warn "Email sent" if $debug;
        unlink $filename;
    } ## end if ( $fh && flock( $fh, LOCK_EX | LOCK_NB ...
} ## end sub processMailQueueFile
